<!--
@description    漏斗分析
@author         秦俊强
@email          458112865@qq.com
@create         2021-05-26
-->

<template>
  <div class="funnelAnalysis" v-loading="loading">
    <!-- 侧边弹窗 编辑/添加 漏斗 start -->
    <el-drawer
      :title="getDrawerTitle()"
      :visible.sync="showEditFunnel"
      :modal-append-to-body="false"
      size="800px"
      append-to-body
    >
      <EditFunnel
        ref="editFunnelRel"
        :d="editFunnelVal"
        @close="showEditFunnel = false"
        @showeditbool="editFlag"
        @getFunnelsEvent="getFunnels"
      ></EditFunnel>
    </el-drawer>
    <!-- 侧边弹窗 编辑/添加 漏斗 end -->

    <!-- 模块标题区 start -->
    <div class="headerBox">
      <div class="title">漏斗分析</div>
      <div class="headerRight">
        <!--        <div class="titleRight">-->
        <!--          <span style="margin: 0 15px">分析主体选择</span>-->
        <!--          <el-select-->
        <!--                  v-model="subjectselect"-->
        <!--                  size="mini"-->
        <!--          >-->
        <!--            <el-option-->
        <!--                    v-for="item in subject"-->
        <!--                    :key="item.value"-->
        <!--                    :label="item.label"-->
        <!--                    :value="item.value">-->
        <!--            </el-option>-->
        <!--          </el-select>-->
        <!--        </div>-->
        <preserVation
          :bookmarkId="analysisOpts.value.bookmarkId"
          @getSearchFunnelParams="getSearchFunnelParams"
        ></preserVation>
      </div>
    </div>

    <!-- 模块标题区 end -->

    <!-- 筛选项区 start -->
    <div class="filterBox">
      <!-- 显示漏斗 start -->
      <div class="viewFunnelBox">
        <span class="title-size">显示漏斗</span>

        <el-select
          size="mini"
          filterable
          :title="analysisOpts.value.name"
          value-key="id"
          v-model="analysisOpts.value"
          @change="analysisChange"
        >
          <el-option
            v-for="item in analysisOpts.options"
            :style="{ 'max-width': '600px' }"
            :key="item.id"
            :value="item"
            :label="item.name"
            :title="item.name"
          ></el-option>
        </el-select>

        <!-- 编辑漏斗 -->
        <el-button
          type="warning"
          size="mini"
          icon="el-icon-edit"
          plain
          @click="editFunnel('edit')"
          >编辑当前漏斗</el-button
        >

        <!-- 创建漏斗 -->
        <el-button
          type="primary"
          size="mini"
          icon="el-icon-plus"
          plain
          @click="editFunnel('add')"
          >创建新漏斗</el-button
        >
      </div>
      <!-- 显示漏斗 end -->

      <!-- 按 xx 查看漏斗 start -->
      <div class="viewFunnelBox">
        <span class="title-size">按</span>

        <el-select
          size="mini"
          @change="funnelChange()"
          placeholder="总体"
          multiple
          filterable
          clearable
          value-key="name"
          v-model="viewFunnelTypes.arr_check"
          :style="{ width: '443px' }"
        >
          <el-option
            v-for="item in viewFunnelTypes.commonOpts"
            :key="item.name"
            :value="item"
            :style="{ 'max-width': '600px' }"
            :label="item.cname"
            :title="item.cname"
          ></el-option>
        </el-select>

        <span style="color: #808080">查看</span>
      </div>
      <!-- 按 xx 查看漏斗 end -->

      <!-- 设置筛选条件 start -->
      <CustomScreen
        ref="customScreenRef"
        :isSupName="true"
        :supName="'_Anything'"
      ></CustomScreen>
      <!-- 设置筛选条件 end -->

      <!-- 设置筛选条件 -->
      <div class="settingCondition">
        <el-button
          type="text"
          icon="el-icon-plus"
          size="small"
          @click="editCond()"
          >全局筛选条件</el-button
        >

        <el-button
          type="primary"
          :icon="icon"
          :disabled="isDoCompute !== 0"
          size="small"
          class="toDoButton"
          @click="searchFunnel()"
          >分析计算
          <template v-if="icon === 'el-icon-loading'"
            >({{ backTime }}s)</template
          >
        </el-button>
      </div>
    </div>
    <!-- 筛选项区 end -->

    <!-- 主内容区 start -->

    <div class="contentBox">
      <div class="titleBox">
        <i class="el-icon-data-line"></i>
        <span>「{{ analysisOpts.value.name }}」漏斗</span>
      </div>

      <div class="childFilterBox">
        <!-- 切换视图 趋势 | 对比 -->
        <el-radio-group v-model="state" size="mini" @change="stateChange()">
          <el-radio-button :label="'trends'">趋势</el-radio-button>
          <el-radio-button :label="'overview'">对比</el-radio-button>
        </el-radio-group>

        <div class="contrastFunnelBox">
          <span
            v-if="viewFunnelTypes.arr_check.length <= 0 && state === 'overview'"
            >* 需选择按分组查看以获取对比选项</span
          >

          <div
            class="selectedBox"
            v-if="
              state === 'overview' &&
              viewFunnelTypes.arr_check.length > 0 &&
              contrastFunnel.opts.length > 0
            "
          >
            <el-select
              size="mini"
              value-key="ind"
              @change="contrastChange"
              v-model="contrastFunnel.selecteds[0]"
            >
              <el-option
                v-for="item in contrastFunnel.opts"
                :key="item.ind"
                :value="item"
                :label="item.name"
                :title="item.name"
              ></el-option>
            </el-select>

            <span class="vs">VS</span>

            <el-select
              size="mini"
              value-key="ind"
              @change="contrastChange"
              v-model="contrastFunnel.selecteds[1]"
            >
              <el-option
                v-for="item in contrastFunnel.opts"
                :key="item.ind"
                :value="item"
                :label="item.name"
                :title="item.name"
              ></el-option>
            </el-select>
          </div>

          <timeRestrict
            :oldTime="dateS"
            :timeRestrict="timeRestrict"
            @change="dateSChange"
          ></timeRestrict>
        </div>

        <!-- 窗口期 -->
        <!-- <div class="winPeriodBox"> -->
        <!--        <ml-time-select-->
        <!--          style="display: inline-block; margin-right: 20px"-->
        <!--          @timeUnity="timeUnity"-->
        <!--        ></ml-time-select>-->

        <!-- 时间查询区间 -->

        <!--          <div class="title">-->
        <!--            <p>窗口期</p>-->
        <!--            <p>7天</p>-->
        <!--          </div>-->
        <!-- </div> -->
      </div>

      <!-- 趋势 视图 start -->
      <el-row
        :gutter="40"
        v-if="state === 'trends' && funnelReportResData.funnelDetail"
      >
        <!-- 对比-左 -->
        <el-col :span="12">
          <ViewFunnel
            :funnelReportResData="funnelReportResData"
            :userDialogData="userDialogData"
          ></ViewFunnel>
        </el-col>

        <!-- 对比-右 图表 -->
        <el-col :span="12">
          <el-container>
            <div id="chart"></div>
          </el-container>
        </el-col>
      </el-row>
      <!-- 趋势 视图 end -->

      <!-- 对比 视图 start -->
      <el-row
        :gutter="40"
        v-if="state === 'overview' && funnelReportResData.funnelDetail"
      >
        <!-- 对比-左 -->
        <el-col :span="12">
          <ViewFunnel
            :funnelReportResData="funnelReportResData"
            :byValues="contrastFunnel.selecteds[0]"
            :userDialogData="userDialogData"
          ></ViewFunnel>
        </el-col>

        <!-- 对比-右 -->
        <el-col :span="12">
          <ViewFunnel
            :funnelReportResData="funnelReportResData"
            :byValues="contrastFunnel.selecteds[1]"
            :userDialogData="userDialogData"
          ></ViewFunnel>
        </el-col>
      </el-row>
      <!-- 对比 视图 end -->

      <!-- 表格 -->
      <TableFunnel
        :funnelReportResData="funnelReportResData"
        :userDialogData="userDialogData"
      ></TableFunnel>
    </div>
    <!-- 主内容区 end -->
  </div>
</template>

<script>
/* 添加/编辑漏斗弹窗组件 */
import EditFunnel from "./editFunnel";
/*  表格展示组件 */
import TableFunnel from "./tableFunnel";
/* 漏斗视图组件 */
import ViewFunnel from "./viewFunnel";
/* 自定义筛选条件 */
import CustomScreen from "./customScreen";
/*漏斗分析保存*/
import preserVation from "./preserVation";
/*数据类型*/
import DataType from "./dataType.config";
/**
 * api 接口
 * */
import { funnelReportRes, getFunnelList, propertyList } from "./api.config.js";
import TimeSelect from "./timeSelect";

export default {
  name: "funnelAnalysis",
  components: {
    EditFunnel,
    TableFunnel,
    ViewFunnel,
    CustomScreen,
    preserVation,
    DataType,
    "ml-time-select": TimeSelect,
  },
  data() {
    return {
      /* 点击分析计算切换图表 */
      icon: "el-icon-search",
      /* 分析计算倒计时*/
      backTime: 60,
      /* 是否正在计算中*/
      isDoCompute: 0,
      dateS: [], // 开始时间段
      subjectselect: "user_id", //分享主体选择
      subject: [
        {
          value: "user_id",
          label: "用户ID（默认）",
        },
        {
          value: "_ip",
          label: "IP",
        },
        {
          value: "_lib",
          label: "SDK",
        },
        {
          value: "result_number",
          label: "搜索结果数据（次数）",
        },
      ],
      loading: true,

      showEditFunnel: false, // 添加/编辑 漏斗弹窗
      editFunnelVal: null,

      /* 显示漏斗选项 */
      analysisOpts: {
        options: [],
        value: {},
      },

      /* 按xx查看漏斗 & 设置筛选条件 */
      viewFunnelTypes: {
        commonOpts: [],

        arr_check: [], // 按xx查看
        arr_setting: [], // 设置筛选条件
      },

      /* 视图类型 */
      state: "trends", // trends 趋势 | overview 对比

      /* 且 and | 或 or */
      relation: { key: "and", name: "且" },

      /* 趋势图表 */
      chartView: {},

      /* 接口原始数据 */
      funnelReportResData: {},

      /* 窗口期 */
      winPeriod: ["", ""],

      /* 日期选择器，不能选择今天以后的日期 */
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() > Date.now() - 8.64e6;
        },
      },

      /* 对比漏斗 */
      contrastFunnel: {
        opts: [], // 可选对比项
        selecteds: ["", ""], // 已选
      },

      timeRestrict: {
        function: "absolute_time",
        params: [this.getBeforeDate(2), this.getBeforeDate()],
      }, // 动态时间参数

      startDate: this.getBeforeDate(2),
      endDate: this.getBeforeDate(),
      /* 给用户列表传递的数据 */
      userDialogData: {
        fromDate: "",
        toDate: "",
        config: {
          groups: [],
          groupNames: [],
          step: "",
          /*以下三个为固定数值*/
          measures: ["conversion_rate"],
          type: "percent",
          setMarkLine: "false",
        },
        state: "",
        funnelId: "",
        byFields: [],
        byFieldSteps: [],
        sliceStep: "",
        sliceByValues: [],

        /*固定值*/
        extendOverEndDate: "true",
        completeStepRows: "true",
        samplingFactor: "64",
        sliceEndDate: "",
        detail: "true",
        sliceWastageUser: "false",
      },
    };
  },

  created() {
    /**
     * TODO 初始化窗口期，数字 7 应该为动态，暂时写死 7 天，即当前时间往前 7 天的窗口期日期范围
     * 7 - 1 说明含今天，实际就会只有 7 天
     * 只传 7 ，说明不含今天，其实会显示 8 天
     * */
    this.winPeriod[0] = this.getBeforeDate(7 - 1);
    this.winPeriod[1] = this.getBeforeDate();

    this.getFunnels();
  },

  mounted() {
    this.$forceUpdate();
    this.$nextTick(() => {
      // 监听 window 窗口变化，自适应图表
      window.addEventListener("resize", this.autoChart);
    });
  },

  methods: {
    //  追加对比 时间函数
    timeContrast(v) {
      let arr = [0, 0];
      // 同段时间
      if (v == "1") {
        let c = new Date(this.dateS[1]) - new Date(this.dateS[0]);
        arr[1] = new Date(this.dateS[0]) - 24 * 60 * 60 * 1000;
        arr[0] = arr[1] - c;
      }
      // 自定义时间
      if (v == "2") {
        arr[0] = new Date(this.dateS[0]) - 24 * 60 * 60 * 1000;
        arr[1] = new Date(this.dateS[1]) - 24 * 60 * 60 * 1000;
      }
      this.dateD = arr;
    },
    dateSChange(newValue) {
      let { sendTimeArr, timeRestrict } = newValue;
      this.timeRestrict = timeRestrict;
      this.dateS = [sendTimeArr[0], sendTimeArr[1]];
      this.startDate = sendTimeArr[0];
      this.endDate = sendTimeArr[1];
      let contrastStartDate = null;
      let contrastEndDate = null;
      if (this.dateD && this.dateD[0]) {
        let date = new Date(this.dateD[0]);
        let year = date.getFullYear();
        let mon = date.getMonth() + 1;
        let day = date.getDate();
        contrastStartDate = year + "-" + mon + "-" + day;
      }
      if (this.dateD && this.dateD[1]) {
        let date = new Date(this.dateD[1]);
        let year = date.getFullYear();
        let mon = date.getMonth() + 1;
        let day = date.getDate();
        contrastEndDate = year + "-" + mon + "-" + day;
      }

      // this.$emit("conversion", {
      //   unit: this.unit,
      //   startDate,
      //   endDate,
      //   contrastStartDate,
      //   contrastEndDate,
      //   timeRestrict    // 动态时间配置集合
      // });
    },
    timeUnity(time) {
      this.winPeriod = time;
    },
    // 编辑组件传过来的布尔值
    editFlag(bool) {
      console.log("触发");
      console.log(bool);
      this.showEditFunnel = bool;
    },

    /* edit 编辑 | add 添加 漏斗 */
    editFunnel(str) {
      if (str === "edit") {
        this.editFunnelVal = this.analysisOpts.value;
      }
      if (str === "add") {
        this.editFunnelVal = null;
      }

      // 拦截提示，如果是编辑漏斗，但是没有选择漏斗
      if (str === "edit" && (!this.editFunnelVal || !this.editFunnelVal.id)) {
        this.$alert("当前无可编辑漏斗，请先创建漏斗", "提示", {
          type: "warning",
        });
        return;
      }

      // 显示右侧弹窗
      this.showEditFunnel = true;

      setTimeout(() => {
        // 清空 editFunnelRel 数据
        this.$refs.editFunnelRel.initializeData();

        // 给 editFunnelRel 控件发送当前选择数据
        if (str === "edit") {
          this.$refs.editFunnelRel.receiveDate(this.editFunnelVal);
        }
      }, 500);
    },

    /* 返回 编辑/添加 漏斗弹窗 title */
    getDrawerTitle() {
      if (!this.editFunnelVal) {
        return "创建漏斗";
      }
      return "编辑漏斗";
    },

    /* 监听【显示漏斗】下拉菜单值的改变 */
    analysisChange() {
      console.log("显示漏斗 = ", this.analysisOpts.value);
    },

    /* 监听【按xx查看】下拉选项值的改变 */
    funnelChange() {
      console.log("按 xx 查看 = ", this.viewFunnelTypes.arr_check);
    },

    /* 视图类型切换 */
    stateChange() {
      if (this.state === "trends") {
        this.viewChart();
      }
    },

    /* 监听对比下拉选项改变 */
    contrastChange() {
      console.log("监听对比下拉选项改变");
    },

    /* 渲染图表 */
    viewChart() {
      let t = this;

      // 如果当前是 对比 视图，则不需要展示图表
      if (t.state === "overview") {
        return;
      }

      let dom = document.getElementById("chart");
      t.chartView = t.$echarts.init(dom);

      // 图表模板
      let tem = {
        xAxis: {
          type: "category",
          axisLabel: { interval: 0, rotate: -40 },
          data: [],
        },
        tooltip: {
          trigger: "axis",
        },
        legend: {
          data: [],
        },
        yAxis: {
          type: "value",
          axisLabel: {
            formatter: "{value} %",
          },
        },
        series: [],
      };

      let funnelReportResData = t.funnelReportResData;
      let dateList = funnelReportResData.dateList;
      let funnelDetail = funnelReportResData.funnelDetail;
      let events = funnelReportResData.events;
      let byValuesList = funnelReportResData.byValuesList;
      let byFields = funnelReportResData.byFields;
      // 图表横坐标，因为 dateList 第 0 个是 '$ALL'，所以从第 1 个开始
      for (let i = 1; i < dateList.length; i++) {
        tem.xAxis.data.push(dateList[i]);
      }

      // 步骤
      if (byFields.length >= 1) {
        for (let i = 0; i < byValuesList.length; i++) {
          console.log("byValuesList[i].toString: ", byValuesList[i].toString());
          let size = i === 0 ? "总体" : byValuesList[i].toString();
          tem.legend.data.push(size);
          tem.series.push({
            name: size,
            type: "line",
            data: [],
          });
        }
      } else {
        for (let i = 0; i < events.length; i++) {
          let size = i === 0 ? "总体转化" : "第 " + i + " 步转化";
          tem.legend.data.push(size);
          tem.series.push({
            name: size,
            type: "line",
            data: [],

            // 参考线/辅助线
            markLine: { data: [{ type: "average", name: "平均值" }] },
          });
        }
      }

      // 坐标值
      for (let i = 1; i < dateList.length; i++) {
        let item = funnelDetail[i];
        if (byFields.length >= 1) {
          for (let j = 0; j < item.overview.length; j++) {
            let cItem = item.overview[j];
            let num =
              cItem[cItem.length - 1].convertedUser === 0
                ? 0
                : cItem[cItem.length - 1].convertedUser /
                  cItem[0].convertedUser;
            num = (Number(num) * 100).toFixed(2);
            tem.series[j].data.push(num);
          }
        } else {
          for (let j = 0; j < item.overview[0].length; j++) {
            let cItem = item.overview[0][j];
            if (j === 0) {
              tem.series[j].data.push(item.completionRate);
            } else {
              tem.series[j].data.push(cItem.completionRate);
            }
          }
        }
      }

      t.chartView.clear();
      console.log(tem);
      t.chartView.setOption(tem);
      t.autoChart();
    },

    /* 图表大小自适应 */
    autoChart() {
      // 如果当前是 对比 视图，则不需要渲染图表
      if (this.state === "overview") {
        return;
      }

      this.chartView && this.chartView.resize();
    },

    /* 添加 add 筛选条件 */
    editCond() {
      this.$refs.customScreenRef.editCond();
    },

    /* 返回 byFields */
    getByFields() {
      let arr = [];
      let arrCheck = this.viewFunnelTypes.arr_check;

      if (arrCheck.length === 0) {
        return arr;
      }

      for (let i = 0; i < arrCheck.length; i++) {
        let item = arrCheck[i];
        arr.push("event._Anything." + item.name);
      }

      return arr;
    },

    /* 初始化对比选项 */
    initContrastFunnelOpts() {
      let t = this;
      t.contrastFunnel.opts = [];
      t.contrastFunnel.selecteds = [
        { ind: 0, name: "总体" },
        { ind: 0, name: "总体" },
      ];

      if (t.viewFunnelTypes.arr_check.length <= 0) {
        return;
      }

      let byValuesList = t.funnelReportResData.byValuesList;
      for (let i = 0; i < byValuesList.length; i++) {
        let arr = byValuesList[i];
        let str = "";

        for (let j = 0; j < arr.length; j++) {
          let val = arr[j];
          str = str + val + (j === arr.length - 1 ? "" : ", ");
        }
        if (i === 0) {
          t.contrastFunnel.opts.push({ ind: 0, name: "总体" });
        } else {
          t.contrastFunnel.opts.push({ ind: i, name: str });
        }
      }

      // 默认总体
      t.contrastFunnel.selecteds[0] = t.contrastFunnel.opts[0];
      t.contrastFunnel.selecteds[1] = t.contrastFunnel.opts[1];
    },

    formatData() {
      let arr = [];
      this.$refs.customScreenRef.arrSetting.map((item) => {
        let unit = {
          field: item.dbColumnName,
          function: item.new_data_type.key,
          params: item.customArr,
        };
        arr.push(unit);
      });
    },

    getSearchFunnelParams(callback) {
      let t = this;
      // 没有选择漏斗，或没有漏斗选项时，不往下执行
      if (!t.analysisOpts.value.id) {
        t.loading = false;

        this.$message("请选择显示漏斗", "提示", { type: "warning" });
        return;
      }

      let byFieldSteps = [];

      for (let i = 0; i < this.viewFunnelTypes.arr_check.length; i++) {
        byFieldSteps.push(i);
      }

      let filter = this.$refs.customScreenRef.getFilterConditions();
      let filterFieldSteps = [];
      if (filter.conditions !== undefined) {
        for (let i = 0; i < filter.conditions.length; i++) {
          filterFieldSteps.push(0);
        }
      }

      let params = {
        req: {
          fromDate: t.startDate, // 窗口期 开始时间
          toDate: t.endDate, // 窗口期 结束时间
          funnelId: t.analysisOpts.value.id, // 当前已选漏斗 id
          byFields: t.getByFields(), // 按 xx 查看
          bookmarkId: "",
          filter: filter, // 自定义漏斗筛选
          byFieldSteps: byFieldSteps,
          bucketParams: {},
          subTaskType: "FUNNEL", // 漏斗模块写死的值
          filterFieldSteps: filterFieldSteps,
          subjectId: this.subjectselect,
          timeRestrict: this.timeRestrict,
        },
        operationCtx: {},
      };
      callback(params);
    },
    /* 查询漏斗内容 */
    searchFunnel() {
      let t = this;
      let appid = this.$store.state.global.appItem.appId;

      // 没有选择漏斗，或没有漏斗选项时，不往下执行
      if (!t.analysisOpts.value.id) {
        t.loading = false;

        this.$message("请选择显示漏斗", "提示", { type: "warning" });
        return;
      }

      let byFieldSteps = [];

      for (let i = 0; i < this.viewFunnelTypes.arr_check.length; i++) {
        byFieldSteps.push(i);
      }

      let filter = this.$refs.customScreenRef.getFilterConditions();
      let filterFieldSteps = [];
      if (filter.conditions !== undefined) {
        for (let i = 0; i < filter.conditions.length; i++) {
          filterFieldSteps.push(0);
        }
      }

      let param = {
        req: {
          fromDate: t.startDate, // 窗口期 开始时间
          toDate: t.endDate, // 窗口期 结束时间
          funnelId: t.analysisOpts.value.id, // 当前已选漏斗 id
          byFields: t.getByFields(), // 按 xx 查看
          bookmarkId: "",
          filter: filter, // 自定义漏斗筛选
          byFieldSteps: byFieldSteps,
          bucketParams: {},
          subTaskType: "FUNNEL", // 漏斗模块写死的值
          filterFieldSteps: filterFieldSteps,
          subjectId: this.subjectselect,
          timeRestrict: this.timeRestrict,
        },
        operationCtx: {},
      };

      t.isDoCompute = 1;

      /* 替换按钮图标 表示加载中 */
      t.icon = "el-icon-loading";
      t.backTimeNumber();

      funnelReportRes(param, appid)
        .then((res) => {
          t.icon = "el-icon-search";
          if (res.data.success !== true) {
            t.$message.error(res.data.errorMessage);
            return;
          }

          console.log("漏斗内容 = ", res.data.value);

          // TODO 特殊接口，暂不需要弹窗提示
          // if (res.data.success !== true) {
          //   t.loading = false;
          //   this.$alert(res.data.msg, '提示', { type: 'warning'});
          //   return;
          // }

          /*数据重新初始化*/
          /*以下字段每次请求都会刷新*/
          t.userDialogData.config.groups = [];
          t.userDialogData.config.groupNames = [];
          t.userDialogData.config.step = "";
          t.userDialogData.state = "";
          t.userDialogData.funnelId = "";
          t.userDialogData.byFields = [];
          t.userDialogData.byFieldSteps = [];
          t.userDialogData.sliceStep = "";
          t.userDialogData.sliceByValues = [];
          t.userDialogData.filter = {};
          /* 把参数放入到用户列表对象 */
          t.userDialogData.fromDate = t.startDate;
          t.userDialogData.toDate = t.endDate;
          t.userDialogData.state = t.state;
          t.userDialogData.funnelId = t.analysisOpts.value.id;
          t.userDialogData.byFields = res.data.value.byFields;
          t.userDialogData.filter = filter;
          for (let i = 0; i < res.data.value.byFields.length; i++) {
            t.userDialogData.byFieldSteps.push("0");
          }

          /*用户列表对象的config拼接*/
          for (let i = 0; i < res.data.value.byValuesList.length; i++) {
            let groupNames = "";
            for (let j = 0; j < res.data.value.byValuesList[i].length; j++) {
              if (res.data.value.byValuesList[i][j] === null) {
                groupNames = groupNames + "null,";
              } else {
                groupNames =
                  groupNames +
                  res.data.value.byValuesList[i][j].toString() +
                  ",";
              }
            }
            if (groupNames.length > 0) {
              groupNames = groupNames.substring(0, groupNames.length - 1);
            }

            t.userDialogData.config.groups.push(i.toString());
            t.userDialogData.config.groupNames.push(groupNames);
          }
          if (
            res.data.value.byValuesList.length === 1 &&
            res.data.value.byValuesList[0][0] === "$ALL"
          ) {
            t.userDialogData.config.step = "$ALL";
          }

          t.funnelReportResData = res.data.value;
          t.initContrastFunnelOpts();
          this.formatData();

          setTimeout(() => {
            t.viewChart();
          });
        })
        .catch((error) => {
          t.icon = "el-icon-search";
          t.$message.error(error);
        });
    },

    /* 分析计算到倒计时*/
    backTimeNumber() {
      if (this.icon !== "el-icon-search") {
        if (this.backTime >= 0) {
          this.backTime--;
          setTimeout(this.backTimeNumber, 1000);
        } else {
          t.$message.error("计算超时");
        }
      } else {
        this.isDoCompute = 0;
        this.backTime = 60;
        return;
      }
    },

    /* 获取【漏斗】下拉菜单列表 */
    getFunnels() {
      let t = this;
      t.loading = true;

      let param = {
        req: {
          currentPage: 1,
          pageSize: 50,
          bookmarkId: "",
          appId: "",
          limit: 20,
        },
        operationCtx: {},
      };
      getFunnelList(param)
        .then((res) => {
          // 返回状态码如果不是 200，说明数据异常，需弹窗提示
          if (res.data.success !== true) {
            t.loading = false;
            t.$message.error(res.data.errorMessage);
            return;
          }

          let data = res.data.value;

          if (data && data.list && data.list[0]) {
            t.analysisOpts.options = data.list;
            t.analysisOpts.value = t.analysisOpts.options[0];
          } else {
            t.analysisOpts.options = [];
            t.analysisOpts.value = {};
          }

          this.getFunnelCondition();
        })
        .catch((error) => {
          t.loading = false;
          console.log("error = ", error);
        });
    },

    /* 获取【按 xx 条件查看】下拉菜单选项 */
    getFunnelCondition() {
      let t = this;
      t.loading = true;

      let param = {
        req: {
          events: ["_Anything"],
          type: "event",
          needEventTime: true,
        },
        operationCtx: {},
      };

      propertyList(param)
        .then((res) => {
          // 返回状态码如果不是 200，说明数据异常，需弹窗提示
          if (res.data.success !== true) {
            t.loading = false;
            t.$message.error(res.data.errorMessage);
            return;
          }
          t.loading = false;
          t.viewFunnelTypes.commonOpts = res.data.value.list;
        })
        .catch((error) => {
          t.loading = false;
          console.log("error = ", error);
        });
    },

    /**
     * 返回前 number 天的日期，参数 number 为前几天
     *
     * 不传 number，返回当前时间 yyyy-MM-dd
     * 传 number，例如 7，返回当前时间往前 7 天的时间
     * */
    getBeforeDate(number) {
      let num = number;
      let date = new Date();

      let year = date.getFullYear();
      let mon = date.getMonth() + 1;
      let day = date.getDate();

      if (typeof num === "number") {
        if (day <= num) {
          if (mon > 1) {
            mon = mon - 1;
          } else {
            year = year - 1;
            mon = 12;
          }
        }

        date.setDate(date.getDate() - num);

        year = date.getFullYear();
        mon = date.getMonth() + 1;
        day = date.getDate();
      }

      return (
        year +
        "-" +
        (mon < 10 ? "0" + mon : mon) +
        "-" +
        (day < 10 ? "0" + day : day)
      );
    },
  },
};
</script>

<style scoped lang="scss">
.funnelAnalysis {
  padding: 15px;
}

.toDoButton {
  width: 192px;
  position: absolute;
  right: 15px;
}

.headerBox {
  display: flex;
  justify-content: space-between;
}
.title {
  font-size: 18px;
  font-weight: bold;
  padding-left: 10px;
}
.headerRight {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  .titleRight {
    display: flex;
    align-items: center;
  }
}

.filterBox,
.contentBox {
  padding: 10px 15px;
  background-color: #ffffff;
  border-radius: 5px;
  margin: 15px 0;
  box-shadow: 0 2px 11px rgba(190, 202, 218, 0.17);
}

/* 筛选项区 */
.filterBox {
  .viewFunnelBox {
    margin-right: 15px;
    padding: 10px 0;
    border-bottom: 1px solid #e7e7e7;
    position: relative;

    button {
      height: 27px;
    }

    .title-size {
      display: inline-block;
      width: 80px;
      padding: 0 10px;
      text-align: right;
    }

    .el-select {
      margin-right: 10px;
    }
  }

  .funnelSettingBox {
    border-left: 2px solid #6fd3b3;
    padding: 5px 0 5px 97px;
    position: relative;

    &:hover {
      background-color: #fafafa;
    }

    ::v-deep input[type="number"] {
      padding-right: 0;
    }

    .el-select {
      margin-right: 10px;
    }

    .size {
      padding-right: 5px;
    }

    .betweenBox,
    .datetimeBox {
      display: inline-block;
    }
  }

  i.el-icon-delete {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translate(0, -50%);
    cursor: pointer;

    &:hover {
      color: rgb(247, 86, 94);
    }
  }

  .andOrNotBox,
  .lineBox {
    position: absolute;
    top: 50%;
  }
  /* 且或非 */
  .andOrNotBox {
    width: 26px;
    height: 26px;
    font-size: 12px;
    text-align: center;
    line-height: 26px;
    border: 1px solid #cccccc;
    background-color: #fafafa;
    border-radius: 3px;
    cursor: pointer;
    z-index: 10;
    transform: translate(46px, -50%);
  }

  .lineBox {
    width: 26px;
    border: 1px solid #cccccc;
    border-right: none;
    transform: translate(60px, -50%);
    z-index: 5;
  }

  /* 设置筛选条件 */
  .settingCondition {
    padding: 10px 10px 0 100px;
  }
}

/* 主内容区 */
.contentBox {
  .titleBox {
    text-align: center;
    font-size: 16px;
    font-weight: bold;
    padding: 10px 0;
    margin-bottom: 10px;
  }

  .childFilterBox {
    padding: 10px 0 15px 0;
    margin-bottom: 20px;
    border-bottom: 1px solid #e7e7e7;

    .winPeriodBox {
      float: right;

      .title {
        float: right;
        font-size: 12px;

        p {
          margin: -2px 0 -2px 10px;
        }
        p:nth-child(1) {
          color: #cccccc;
        }
      }
    }

    .el-radio-group {
      float: left;
    }
    .el-range-editor.el-input__inner {
      padding: 0 10px;
    }

    ::v-deep .el-range-editor--mini .el-range__close-icon {
      display: none;
    }
    ::v-deep .el-range-editor--mini .el-range-separator {
      line-height: 25px;
    }

    /* 对比选项 */
    .contrastFunnelBox {
      font-size: 12px;
      display: inline-block;
      padding: 0 10px;

      .vs {
        padding: 0 5px;
        font-size: 14px;
        font-weight: bold;
      }
    }
  }

  .el-row {
    margin-right: 0 !important;
    margin-left: 0 !important;
    margin-bottom: 50px;

    .el-col:nth-child(1) {
      height: 420px;
      border-right: 1px solid #e7e7e7;
      padding-left: 0 !important;
      overflow: auto;
    }

    .el-col:nth-child(2) {
      padding-right: 0 !important;
    }
  }

  /*.el-row .el-col,*/
  #chart {
    width: 100%;
    height: 60vh;
    position: relative;
  }
}
</style>

